<?php


namespace App\Services\Goods;

use App\Exceptions\BusinessException;
use App\Common\ResponseCode;
use App\Models\Goods\Specs;
use App\Models\Goods\SpecValue;
use App\Services\BaseService;
use Illuminate\Support\Facades\DB;

/**
 * 商品规格相关业务类
 *
 * @author WangBin
 * @date 2021-09-24
 * @package App\Http\Services
 */
class SpecsService extends BaseService
{
    /**
     * 保存规格
     *
     * @param array $data
     * @return mixed
     * @throws BusinessException
     */
    public function update(array $data)
    {
        if(!empty($data['spec_id'])) {
            $spec = Specs::getById($data['spec_id']);
            if(is_null($spec)) {
                throw new BusinessException(ResponseCode::GOODS_SPEC_NOT_FOUND);
            }
        }
        // 校验规格名唯一
        $ret = Specs::checkUnique('spec_name', $data['spec_name'], $data['spec_id']);
        if($ret) {
            throw new BusinessException(ResponseCode::GOODS_SPEC_NAME_EXIST);
        }
        // 校验规格编号唯一
        $ret = Specs::checkUnique('spec_bn', $data['spec_bn'], $data['spec_id']);
        if($ret) {
            throw new BusinessException(ResponseCode::GOODS_SPEC_BN_EXIST);
        }
        return Specs::saveData($data);
    }

    /**
     * 规格列表
     *
     * @param array $filter
     * @return array
     */
    public function getList(array $filter)
    {
        $result = ['total' => 0, 'list' => []];
        $specs = Specs::getByFilter($filter);
        if(empty($filter['no_page'])) {
            $specs->offset($filter['page'] * $filter['limit'])->limit($filter['limit']);
        }
        $result['total'] = $specs->count();
        // 获取规格值
        $specs = $specs->get();
        if(isset($filter['with_value'])) {
            $specs->each(function ($item){
                $item['values'] = SpecValue::getBySpecId($item->spec_id);
            });
        }
        $result['list'] = $specs;
        return $result;
    }

    /**
     * 获取规格详情
     *
     * @param int $specId
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws BusinessException
     */
    public function get(int $specId)
    {
        $spec = Specs::getById($specId);
        if(is_null($spec)) {
            throw new BusinessException(ResponseCode::GOODS_SPEC_NOT_FOUND);
        }
        return $spec;
    }

    /**
     * 删除规格
     *
     * @param string $specId
     * @return mixed
     */
    public function delete(string $specId)
    {
        $specIds = explode(',', $specId);
        return Specs::remove($specIds);
    }

    /**
     * 根据规格获取配置的值
     *
     * @param int $specId
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getValList(int $specId)
    {
        return SpecValue::getBySpecId($specId);
    }

    /**
     * 保存规格值
     *
     * @param int $specId
     * @param array $vals
     * @return bool
     * @throws BusinessException
     */
    public function updateVals(int $specId, array $vals)
    {
        $spec = Specs::getById($specId);
        if(is_null($spec)) {
            throw new BusinessException(ResponseCode::GOODS_SPEC_NOT_FOUND);
        }
        try {
            DB::beginTransaction();
            foreach ($vals as $val)
            {
                // 值是否存在
                $specValue = SpecValue::getById($val['value_id']);
                if(is_null($specValue)) {
                    // 新增
                    SpecValue::saveData(0, ['spec_id' => $specId, 'value' => $val['value']]);
                } else {
                    // 更新
                    SpecValue::saveData($specValue->value_id, ['spec_id' => $specId, 'value' => $val['value']]);
                }
            }
            DB::commit();
        } catch (\Exception $exception) {
            logger($exception->getMessage());
            DB::rollBack();
        }
        return true;
    }

    /**
     * 删除规格值
     *
     * @param int $valueId
     * @return mixed
     */
    public function deleteVal(int $valueId)
    {
        return SpecValue::removeById($valueId);
    }
}
